home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK2.toast / Development Kits (Disc 2) / QuickTime Conferencing / Programming Stuff / Sample Code / SeeWorld / SplitSee.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-10  |  12.2 KB  |  685 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        SplitSee.c
  3.  
  4.     Contains:    A Sample MovieTalk Conferencing Application
  5.  
  6.     Written by:    Guy Riddle
  7.  
  8.     Copyright:    © 1994 by Apple Computer, Inc., all rights reserved.
  9.  
  10. */
  11.  
  12. #include <Types.h>
  13. #include <QuickDraw.h>
  14. #include <Fonts.h>
  15. #include <Events.h>
  16. #include <Windows.h>
  17. #include <Menus.h>
  18. #include <Dialogs.h>
  19. #include <Desk.h>
  20. #include <ToolUtils.h>
  21. #include <Memory.h>
  22. #include <SegLoad.h>
  23. #include <Files.h>
  24. #include <Folders.h>
  25. #include <OSUtils.h>
  26. #include <DiskInit.h>
  27. #include <Scrap.h>
  28.  
  29. #include <String.h>
  30. #include <Strings.h>
  31. #include <stdio.h>
  32.  
  33. #include <QuickTimeConferencing.h>
  34.  
  35. #include "See.h"
  36.  
  37. typedef    EventRecord            *EventRecordPtr;
  38. typedef    Byte                *BytePtr;
  39.  
  40. #define        MAXMEMBERS        5
  41.  
  42. typedef struct {
  43.     MTConferenceMember        member;
  44.     MTControllerComponent    controller;
  45. } Member, *MemberPtr;
  46.  
  47.     Member                    gMember[MAXMEMBERS+1];
  48.                             
  49.     Rect                    gWindowBox                = { 100, 80, 220, 240 };
  50.     Rect                    gVoiceBox                = { 50, 180, 50, 380 };
  51.                             
  52.     MTCString63                gUserName, vwTitle, awTitle;
  53.     
  54.     ComponentInstance        gCC, gBC;
  55.     MTConferenceToken        gConference;
  56.     MTControllerComponent    gVoice;
  57.     
  58.     ComponentInstance        gBD;
  59.     Rect                    gTheDot                    = { 5, 5, 15, 15 };
  60.     PixPatHandle            gDotPat;
  61.     RgnHandle                gNoClip, gDotClip;
  62.     RGBColor                gDotColor;
  63.     
  64.     MemberPtr        FindMember(MTConferenceMember);
  65.     
  66.     void            Initialize(void);
  67.     void            StartMovieTalk(void);
  68.     void            InitializeBlueDot(void);
  69.     void            StopMovieTalk(void);
  70.     void            EventLoop(void);
  71.     
  72.     void            DoToolboxEvent(EventRecordPtr);
  73.     void            DoKeyDownEvent(EventRecordPtr);
  74.     void            DoMouseDownEvent(EventRecordPtr);
  75.     void            DoDiskEvent(EventRecordPtr);
  76.     void            UpdateDot(void);
  77.     void            AdjustMenus(void);
  78.     void            DoMenuBar(long);
  79.     void            DoAppleMenu(short);
  80.     void            DoFileMenu(short);
  81.     void            DoVideoPhoneMenu(short);
  82.     void            DoMenuCall(void);
  83.     void            DoMenuHangUp(void);
  84.     void            DoMenuVoiceOn(void);
  85.     
  86.     void            DoConferenceEvent(MTConferenceEventPtr);
  87.     void            DoConfReady(MTConferenceEventPtr);
  88.     void            DoMemberReady(MTConferenceEventPtr);
  89.     void            DoMemberTerminated(MTConferenceEventPtr);
  90.     void            DoConfTerminated(MTConferenceEventPtr);
  91.     void            DoAuxTerminated(MTConferenceEventPtr);
  92.     void            DoIncomingCall(MTConferenceEventPtr);
  93.     void            DoMemberJoining(MTConferenceEventPtr);
  94.  
  95.     void            CallOne(MTNamePtr);
  96.     void            SaveMovie(Handle);
  97.     void            SaveSnapshot(Handle);
  98.     void            Sorry(int, int, MTConferenceMember, OSErr);
  99.     
  100. /*
  101.  *    SplitSee
  102.  *
  103.  *    Another sample conferencing application, compatible with the others in the
  104.  *    SeeWorld family.  Differences between See and SplitSee are
  105.  *
  106.  *    • Server passwords aren't supported
  107.  *
  108.  *    • Incoming media windows are "auto-positioned" on the screen
  109.  *
  110.  *    • To demonstrate use of auxiliary media streams, voice and sound are
  111.  *    separated and the sound can be added or removed during a conference
  112.  *
  113.  *    • The self view window contains a Blue Dot to indicate the Happiness value
  114.  *    of the transmit flow control components.
  115.  */
  116.  
  117. void main()
  118. {
  119.     Initialize();
  120.     EventLoop();
  121. }
  122.  
  123.     void 
  124. Initialize(
  125.     void
  126. ){
  127.     Handle                    menuBar;
  128.     DialogPtr                dp;
  129.  
  130.     InitGraf((Ptr) &qd.thePort);
  131.     InitFonts();
  132.     InitWindows();
  133.     InitMenus();
  134.     TEInit();
  135.     InitDialogs(nil);
  136.     InitCursor();
  137.     
  138.     dp = GetNewDialog(rAboutAlert, nil, (WindowRef) -1);
  139.     DrawDialog(dp);
  140.             
  141.     StartMovieTalk();
  142.     InitializeBlueDot();
  143.  
  144.     menuBar = GetNewMBar(rMenuBar);
  145.  
  146.     SetMenuBar(menuBar);
  147.     DisposHandle(menuBar);
  148.     AddResMenu(GetMHandle(mApple), 'DRVR');
  149.     AppendMenu(GetMHandle(mVideoPhone), "\p(-;Talkies");        // (using the same See.r file)
  150.  
  151.     DrawMenuBar();
  152.     
  153.     DisposeDialog(dp);
  154. }
  155.  
  156.     void
  157. StartMovieTalk(
  158.     void
  159. ){
  160.     StringHandle            sh;
  161.  
  162.     sh = GetString(kMTAppleTalkUserName);
  163.     
  164.     strncpy(gUserName, *sh+1, **sh);
  165.     sprintf(vwTitle, "Silent %s", gUserName);
  166.     sprintf(awTitle, "Voice of %s", gUserName);
  167.     
  168.     gCC = OpenDefaultComponent(kMTConferenceType, kMTMovieTalkSubType);
  169.     
  170.     gMember[0].controller = MTConferenceNewPreparedController(gCC, &gWindowBox,
  171.                               mtMediaSourcePrepMask+mtGrabVideoPrepMask+mtWindowVisiblePrepMask+mtControllerVisiblePrepMask+mtEnableSnapshotPrepMask+mtEnableRecordPrepMask,
  172.                               vwTitle);
  173.     
  174.     MTConferenceListen(gCC, vwTitle, gUserName, "mtlkatlk\tVideoPhone\x0Dmtlktcpi\t458\x0Dmtlkisdn\t-\x0D");
  175.     
  176.     gBC = OpenDefaultComponent(kMTBrowserType, kMTAppleTalkSubType);
  177. }                            
  178.  
  179.     void
  180. InitializeBlueDot(
  181.     void
  182. ){
  183.     SetPort((GrafPtr) MTControllerGetControllerPort(gMember[0].controller));
  184.     
  185.     gDotPat = NewPixPat();
  186.     
  187.     gNoClip = NewRgn();
  188.     GetClip(gNoClip);
  189.     
  190.     gDotClip = NewRgn();
  191.     OpenRgn();
  192.     FrameOval(&gTheDot);
  193.     CloseRgn(gDotClip);
  194.     XorRgn(gNoClip, gDotClip, gDotClip);
  195.     
  196. //    gBD = OpenDefaultComponent(kMTMonitorType, kMTMovieTalkSubType);
  197. }
  198.  
  199.     void
  200. EventLoop(
  201.     void
  202. ){
  203.     EventRecord                tEvent;
  204.     MTConferenceEvent        cEvent;
  205.  
  206.     for(;;){
  207.         if(MTConferenceGetNextEvent(gCC, &cEvent))
  208.             DoConferenceEvent(&cEvent);
  209.             
  210.         if(WaitNextEvent(everyEvent, &tEvent, 1, 0))
  211.             DoToolboxEvent(&tEvent);
  212.         else
  213.             UpdateDot();
  214.     }
  215. }
  216.  
  217.     void
  218. DoToolboxEvent(
  219.     EventRecordPtr            ev
  220. ){
  221.     switch(ev->what){
  222.     case mouseDown:
  223.         DoMouseDownEvent(ev);
  224.         break;
  225.     
  226.     case keyDown:
  227.         DoKeyDownEvent(ev);
  228.         break;
  229.     
  230.     case diskEvt:
  231.         DoDiskEvent(ev);
  232.     }
  233. }
  234.  
  235.     void
  236. UpdateDot(
  237.     void
  238. ){
  239.     long                    happy;
  240.  
  241.     if(!gConference)
  242.         return;
  243.         
  244. //    happy = MTMonitorQueryHappiness(gBD);
  245.     happy = 100;
  246.     
  247.     gDotColor.blue = 600 * happy;
  248.     gDotColor.red = 60000 - gDotColor.blue;
  249.     
  250.     SetPort((GrafPtr) MTControllerGetControllerPort(gMember[0].controller));
  251.  
  252.     MakeRGBPat(gDotPat, &gDotColor);
  253.     FillCOval(&gTheDot, gDotPat);
  254. }
  255.  
  256.     void
  257. DoMouseDownEvent(
  258.     EventRecordPtr            ev
  259. ){
  260.     WindowPtr                wp;
  261.     short                    part;
  262.     
  263.     part = FindWindow(ev->where, &wp);
  264.     
  265.     switch(part){
  266.     case inMenuBar:
  267.         AdjustMenus();
  268.         DoMenuBar(MenuSelect(ev->where));
  269.     }
  270. }
  271.  
  272.     void
  273. DoKeyDownEvent(
  274.     EventRecordPtr            ev
  275. ){
  276.     if(ev->modifiers & cmdKey){
  277.         AdjustMenus();    
  278.         DoMenuBar(MenuKey(ev->message & charCodeMask));
  279.     }
  280. }
  281.  
  282.     void
  283. DoDiskEvent(
  284.     EventRecordPtr            ev
  285. ){
  286.     Point                    where;
  287.  
  288.     if(HiWord(ev->message)){
  289.         SetPt(&where, kDILeft, kDITop);
  290.         DIBadMount(where, ev->message);
  291.     }
  292. }
  293.  
  294.     void
  295. AdjustMenus(
  296.     void
  297. ){
  298.     MenuHandle                mh;
  299.     
  300.     mh = GetMHandle(mVideoPhone);
  301.     
  302.     gConference ? EnableItem(mh, iHangUp) : DisableItem(mh, iHangUp);
  303.     FindMember(0) ? EnableItem(mh, iCall) : DisableItem(mh, iCall);
  304.     
  305.     CheckItem(mh, iVoiceOn, !!gVoice);
  306.     (gConference && !gVoice) ? EnableItem(mh, iVoiceOn) : DisableItem(mh, iVoiceOn);
  307. }
  308.  
  309.     void
  310. DoMenuBar(
  311.     long                    selection
  312. ){
  313.     short                    menuID;    
  314.     short                    menuItem;
  315.  
  316.     menuID = HiWord(selection);
  317.     menuItem = LoWord(selection);
  318.     
  319.     switch(menuID){
  320.     case mApple:
  321.         DoAppleMenu(menuItem);
  322.         break;
  323.         
  324.     case mFile:
  325.         DoFileMenu(menuItem);
  326.         break;
  327.         
  328.     case mEdit:                    /* call SystemEdit for DA editing & MultiFinder */
  329.         SystemEdit(menuItem-1);
  330.         break;
  331.         
  332.     case mVideoPhone:
  333.         DoVideoPhoneMenu(menuItem);
  334.     }
  335.     
  336.     HiliteMenu(0);
  337. }
  338.  
  339.     void
  340. DoAppleMenu(
  341.     short                    item
  342. ){
  343.     DialogRef                dp;
  344.     Str255                    daName;
  345.     short                    itemHit;
  346.  
  347.     switch(item){
  348.     case iAbout:
  349.         dp = GetNewDialog(rAboutAlert, nil, (WindowRef) -1);
  350.         SetDialogDefaultItem(dp, 1);
  351.         
  352.         ModalDialog(0, &itemHit);
  353.         
  354.         DisposeDialog(dp);
  355.         break;
  356.         
  357.     default:            /* all non-About items in this menu are DAs */
  358.         GetItem(GetMHandle(mApple), item, daName);
  359.         OpenDeskAcc(daName);
  360.     }
  361. }
  362.  
  363.     void
  364. DoFileMenu(
  365.     short                    item
  366. ){
  367.     switch(item){
  368.     case iQuit:
  369.         StopMovieTalk();
  370.         
  371.         ExitToShell();
  372.     }
  373. }
  374.  
  375.     void
  376. DoVideoPhoneMenu(
  377.     short                    item
  378. ){
  379.     switch(item){
  380.     case iCall:
  381.         DoMenuCall();
  382.         break;
  383.         
  384.     case iHangUp:
  385.         DoMenuHangUp();
  386.         break;
  387.         
  388.     case iVoiceOn:
  389.         DoMenuVoiceOn();
  390.     }
  391. }
  392.  
  393.     void
  394. StopMovieTalk(
  395.     void
  396. ){
  397.     CloseComponent(gCC);
  398.     CloseComponent(gBC);
  399. }
  400.  
  401.     void
  402. DoMenuCall(
  403.     void
  404. ){
  405.     MTNameListPtr            names;
  406.     MTNamePtr                np;
  407.     int                        count;
  408.     
  409.     if(MTBrowserBrowse(gBC, 0, "\pLets go Fishing…", "mtlkatlk\tVideoPhone\x0Dmtlkatlk\tMulticaster\x0D", 0, &names) != noErr)
  410.         return;
  411.         
  412.     count = GetMTNameListCount(names);
  413.     np = &(names->list[0]);
  414.  
  415.     while(--count >= 0)
  416.         CallOne(np++);
  417.         
  418.     DisposeMTNameList(names);
  419. }
  420.  
  421.     void
  422. CallOne(
  423.     MTNamePtr                np
  424. ){
  425.     MemberPtr                mp;
  426.     
  427.     if(!(mp = FindMember(0)))
  428.         return;
  429.         
  430.     mp->member = MTConferenceCall(gCC, "See Wiz", np);
  431. }
  432.  
  433.     void
  434. DoMenuHangUp(
  435.     void
  436. ){
  437.     MTConferenceTerminate(gCC, gConference);
  438.     MTControllerSetClip(gMember[0].controller, 0, gNoClip);
  439.     gConference = 0;        // just to suppress menu choice
  440. }
  441.  
  442.     void
  443. DoMenuVoiceOn(
  444.     void
  445. ){
  446.     gVoice = MTConferenceNewPreparedController(gCC, &gVoiceBox,
  447.                mtMediaSourcePrepMask+mtGrabAudioPrepMask+mtAuxiliaryClosePrepMask+mtWindowVisiblePrepMask+mtControllerVisiblePrepMask+mtEnableRecordPrepMask,
  448.                awTitle);
  449.                
  450.     MTConferenceAttachAuxiliarySource(gCC, gConference, gVoice, awTitle);
  451. }
  452.  
  453.     void
  454. DoConferenceEvent(
  455.     MTConferenceEventPtr    ce
  456. ){
  457.     switch(ce->what){
  458.     case mtIncomingCallEvent:
  459.         DoIncomingCall(ce);
  460.         break;
  461.     
  462.     case mtMemberJoiningEvent:
  463.         DoMemberJoining(ce);
  464.         break;
  465.  
  466.     case mtConferenceReadyEvent:
  467.         DoConfReady(ce);
  468.         break;
  469.     
  470.     case mtConferenceTerminatedEvent:
  471.         DoConfTerminated(ce);
  472.         break;
  473.     
  474.     case mtAuxiliaryTerminatedEvent:
  475.         DoAuxTerminated(ce);
  476.         break;
  477.     
  478.     case mtMemberReadyEvent:
  479.         DoMemberReady(ce);
  480.         break;
  481.     
  482.     case mtMemberTerminatedEvent:
  483.         DoMemberTerminated(ce);
  484.         break;
  485.     
  486.     case mtRefusedEvent:
  487.         Sorry(701, 1, ce->who, ce->err);
  488.         break;
  489.     
  490.     case mtFailedEvent:
  491.         Sorry(701, 2, ce->who, ce->err);
  492.         break;
  493.         
  494.     case mtSnapshotTakenEvent:
  495.         SaveSnapshot(ce->surprise);
  496.         break;
  497.         
  498.     case mtMovieRecordedEvent:
  499.         SaveMovie(ce->surprise);
  500.     }
  501.     
  502.     if(ce->surprise)
  503.         DisposeHandle(ce->surprise);
  504. }
  505.  
  506.     void
  507. DoIncomingCall(
  508.     MTConferenceEventPtr    ce
  509. ){
  510.     MemberPtr                mp;
  511.     OSErr                    reason;
  512.     
  513.     reason = 0;
  514.     
  515.     if((ce->bonus & mtSendMediaModeMask) && !(ce->bonus & mtReceiveMediaModeMask))
  516.         reason = mtConnectionRefusedErr;        // no peeking
  517.     else if(mp = FindMember(0))
  518.         mp->member = ce->who;
  519.     else{
  520.         reason = paramErr;
  521.         
  522.         Sorry(702, 1, ce->who, 0);
  523.     }
  524.         
  525.     MTConferenceReply(gCC, ce->who, reason);
  526. }
  527.  
  528.     void
  529. DoMemberJoining(
  530.     MTConferenceEventPtr    ce
  531. ){
  532.     MemberPtr                mp;
  533.     
  534.     if(mp = FindMember(0))
  535.         mp->member = ce->who;
  536.     else
  537.         Sorry(702, 2, ce->who, 0);
  538. }
  539.  
  540.     void
  541. DoConfReady(
  542.     MTConferenceEventPtr    ce
  543. ){
  544.     if(gConference)
  545.         MTConferenceMerge(gCC, gConference, ce->who);
  546.     else{
  547.         MTControllerSetClip(gMember[0].controller, 0, gDotClip);
  548.         MTConferenceActivateConference(gCC, gConference = ce->who, gMember[0].controller);
  549.     }
  550. }
  551.  
  552.     void
  553. DoMemberReady(
  554.     MTConferenceEventPtr    ce
  555. ){
  556.     MemberPtr                mp;
  557.     MTControllerComponent    mtc;
  558.     
  559.     
  560.     if(ce->bonus & mtReceiveMediaModeMask){    
  561.         if(!(mp = FindMember(ce->who)))
  562.             return;
  563.     
  564.         mtc = MTConferenceNewPreparedController(gCC, &gWindowBox,
  565.                mtAutoPositionPrepMask+mtWindowVisiblePrepMask+mtControllerVisiblePrepMask+mtEnableSnapshotPrepMask+mtEnableRecordPrepMask,
  566.                MTConferenceGetMemberName(gCC, mp->member));
  567.                
  568.         mp->controller = mtc;
  569.     }else
  570.         mtc = 0;
  571.                        
  572.     MTConferenceActivateMember(gCC, ce->who, mtc);
  573. }
  574.  
  575.     void
  576. DoMemberTerminated(
  577.     MTConferenceEventPtr    ce
  578. ){
  579.     MemberPtr                mp;
  580.     
  581.     if(!(mp = FindMember(ce->who)))
  582.         return;
  583.         
  584.     if(mp->controller)
  585.         MTConferenceDisposeController(gCC, mp->controller);
  586.         
  587.     mp->controller = 0;
  588.     mp->member = 0;
  589. }
  590.  
  591.     void
  592. DoConfTerminated(
  593.     MTConferenceEventPtr    ce
  594. ){
  595.     if(gConference == ce->who){
  596.         MTControllerSetClip(gMember[0].controller, 0, gNoClip);
  597.         
  598.         gConference = 0;
  599.     }
  600. }
  601.  
  602.     void
  603. DoAuxTerminated(
  604.     MTConferenceEventPtr    /* unused */
  605. ){
  606.     MTConferenceDisposeController(gCC, gVoice);
  607.     
  608.     gVoice = 0;
  609. }
  610.  
  611.     void
  612. SaveSnapshot(
  613.     Handle                    pic
  614. ){
  615.     ZeroScrap();
  616.     
  617.     HLock(pic);
  618.     
  619.     PutScrap(GetHandleSize(pic), 'PICT', *pic);
  620. }
  621.  
  622.     void
  623. SaveMovie(
  624.     Handle                    h
  625. ){
  626.     Ptr                        p;
  627.     int                        i;
  628.     long                    dirid;
  629.     short                    vrefnum;
  630.     FSSpecPtr                temp;
  631.     FSSpec                    spec;
  632.     Str255                    newname;
  633.     
  634.     HLock(h);
  635.     temp =(FSSpecPtr) *h;
  636.     
  637.     FindFolder(kOnSystemDisk, kDesktopFolderType, true, &vrefnum, &dirid);
  638.     FSMakeFSSpec(vrefnum, dirid, "", &spec);
  639.     FSpCatMove(temp, &spec);        // move it to the desktop
  640.     
  641.     FSMakeFSSpec(vrefnum, dirid, temp->name, &spec);
  642.     GetIndString(newname, rWildSTRs, srMovieName);
  643.     p = strchr(newname, '?');
  644.     
  645.     for(i = 1; i < 10; i++){
  646.         *p = '0'+i;
  647.         
  648.         if(FSpRename(&spec, newname) == noErr)
  649.             return;                    // and give it a better name
  650.     }
  651.     
  652.     SysBeep(1);
  653. }
  654.     
  655.     MemberPtr
  656. FindMember(
  657.     MTConferenceMember        who
  658. ){
  659.     int                        i;
  660.     
  661.     for(i = 1; i <= MAXMEMBERS; i++)
  662.         if(who == gMember[i].member)
  663.             return(&gMember[i]);
  664.             
  665.     return(0);
  666. }
  667.  
  668.     void
  669. Sorry(
  670.     int                        why,
  671.     int                        note,
  672.     MTConferenceMember        who,
  673.     OSErr                    err
  674. ){
  675.     Str255                p1, p2, p3;
  676.     
  677.     GetIndString(p1, why, note);
  678.     
  679.     strcpy(p2, MTConferenceGetMemberName(gCC, who));
  680.     sprintf(p3, "%d", err);
  681.     
  682.     ParamText("", p1, c2pstr(p2), c2pstr(p3));
  683.     
  684.     CautionAlert(why, 0);
  685. }